﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static LightCAD.MathLib.Constants;

namespace LightCAD.Three
{

    public class WebGLCubeMaps : IDispose
    {
        private JsObj<Texture, WebGLCubeRenderTarget> cubemaps;
        private WebGLRenderer renderer;
        public WebGLCubeMaps(WebGLRenderer renderer)
        {
            this.renderer = renderer;
            this.cubemaps = new JsObj<Texture, WebGLCubeRenderTarget>();
        }
        public Texture mapTextureMapping(Texture texture, int mapping)
        {

            if (mapping == EquirectangularReflectionMapping)
            {
                texture.mapping = CubeReflectionMapping;
            }
            else if (mapping == EquirectangularRefractionMapping)
            {
                texture.mapping = CubeRefractionMapping;
            }
            return texture;
        }
        public virtual Texture get(Texture texture)
        {
            if (texture != null && texture.isRenderTargetTexture == false)
            {
                var mapping = texture.mapping;

                if (mapping == EquirectangularReflectionMapping || mapping == EquirectangularRefractionMapping)
                {

                    if (cubemaps.has(texture))
                    {

                        var cubemap = cubemaps.get(texture).texture;
                        return mapTextureMapping(cubemap, texture.mapping);

                    }
                    else
                    {

                        var image = texture.image;

                        if (image != null && image.height > 0)
                        {

                            var renderTarget = new WebGLCubeRenderTarget(image.height / 2);
                            renderTarget.fromEquirectangularTexture(renderer, texture);
                            cubemaps.set(texture, renderTarget);

                            texture.addEventListener("dispose", onTextureDispose);

                            return mapTextureMapping(renderTarget.texture, texture.mapping);

                        }
                        else
                        {

                            // image not yet ready. try the conversion next frame

                            return null;

                        }

                    }
                }
            }

            return texture;

        }
        public void onTextureDispose(EventArgs e)
        {

            var texture = (Texture)e.target;

            texture.removeEventListener("dispose", onTextureDispose);

            var cubemap = cubemaps.get(texture);

            if (cubemap != null)
            {

                cubemaps.delete(texture);
                cubemap.dispose();

            }

        }
        public virtual void dispose()
        {

            cubemaps = new JsObj<Texture, WebGLCubeRenderTarget>();

        }

    }
}
